package solutions.ferpa.ztest.ent;

import java.sql.*;
import java.util.ArrayList;
import br.com.telescope.adsrt.dom.*;
import br.com.telescope.adsrt.lib.*;
import br.com.telescope.t2.exception.Severity;
import br.com.telescope.replicator.DmlLog;
import br.com.telescope.t2.config.Config;
import java.util.Map;
import br.com.telescope.t2.config.ConfigParameter;
import java.util.Hashtable;

/**
 * API de persistência de dados da entidade PREFERENCIAS
 * @author Gerado pelo Telescope
 */
public class EntPreferencias extends Entity {
    
    public final static String ENTITY_NAME = "RTPREF.PREFERENCIAS";
    public final static String TABLE_NAME = "PREFERENCIAS";
    
    // <editor-fold defaultstate="collapsed" desc="Contrutores e inicializacao">
    /**
     * Construtores
     */
    public EntPreferencias() {
        super();
        initialize();
    }
    
    public EntPreferencias(BaseRuntime ctx) {
        super();
        initialize(ctx);
    }
    
    @Override
    public String getPrimaryKeyColumn() {
        return "ID";
    }
    
    @Override
    public void initialize(BaseRuntime ctx) {
        super.initialize(ctx);
        initialize();
    }
    
    public void initialize() {
        initCache();
        aId = new DomId(this,"ID", "ID"); 
        aId.setRequired(true);
        oId = new DomId();
        aPreferencia = new DomUpper(this,"PREFERENCIA", "Preferência"); 
        aPreferencia.setRequired(true);
        aPreferencia.setSize(160);
        oPreferencia = new DomUpper();
        aDescricao = new DomTextLong(this,"DESCRICAO", "Descrição"); 
        aDescricao.setDefaultValue("Inserido automaticamente!");
        oDescricao = new DomTextLong();
        aDominio = new DomUpper(this,"DOMINIO", "Domínio"); 
        aDominio.setSize(40);
        aDominio.setDefaultValue("ADSRT.TEXT");
        oDominio = new DomUpper();
        aPorUsuario = new DomFlag(this,"POR_USUARIO", "Por usuário"); 
        aPorUsuario.setRequired(true);
        aPorUsuario.setDefaultValue("N");
        oPorUsuario = new DomFlag();
        aValor = new DomTextLong(this,"VALOR", "Valor"); 
        oValor = new DomTextLong();
        ressetModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributos da entidade">
    
    // ID
    private DomId aId;
    private DomId oId;
    
    // Preferência
    private DomUpper aPreferencia;
    private DomUpper oPreferencia;
    
    // Descrição
    private DomTextLong aDescricao;
    private DomTextLong oDescricao;
    
    // Domínio
    private DomUpper aDominio;
    private DomUpper oDominio;
    
    // Por usuário
    private DomFlag aPorUsuario;
    private DomFlag oPorUsuario;
    
    // Valor
    private DomTextLong aValor;
    private DomTextLong oValor;
    
    // <editor-fold defaultstate="collapsed" desc="Atributo ID">
    
    public EntPreferencias id(Long value) {
        setId(value);
        return this;
    }
    
    public void setId(DomId value) {
        if (value == null || value.isNull()) {
            nullifyId();
        } else {
            aId.setValue(value.getValue());
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(String value) {
        if (value == null) {
            nullifyId();
        } else {
            aId.setValue(value);
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(Long value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void setId(Object value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyId() {
        if (!aId.isNull()) {
            aId.setNull(true);
            setModified(true);
        }
    }
    
    public DomId getId() {
        return aId;
    }
    
    public DomId oldId() {
        return oId;
    }
    
    public Long valueOfId() {
        return aId.getValue();
    }
    
    public boolean isIdModified() {
        return aId.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo PREFERENCIA">
    
    public EntPreferencias preferencia(String value) {
        setPreferencia(value);
        return this;
    }
    
    public void setPreferencia(DomUpper value) {
        if (value == null || value.isNull()) {
            nullifyPreferencia();
        } else {
            aPreferencia.setValue(value.getValue());
            if (aPreferencia.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPreferencia(String value) {
        if (value == null) {
            nullifyPreferencia();
        } else {
            aPreferencia.setValue(value);
            if (aPreferencia.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPreferencia(Object value) {
        aPreferencia.setValue(value);
        if (aPreferencia.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyPreferencia() {
        if (!aPreferencia.isNull()) {
            aPreferencia.setNull(true);
            setModified(true);
        }
    }
    
    public DomUpper getPreferencia() {
        return aPreferencia;
    }
    
    public DomUpper oldPreferencia() {
        return oPreferencia;
    }
    
    public String valueOfPreferencia() {
        return aPreferencia.getValue();
    }
    
    public boolean isPreferenciaModified() {
        return aPreferencia.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo DESCRICAO">
    
    public EntPreferencias descricao(String value) {
        setDescricao(value);
        return this;
    }
    
    public void setDescricao(DomTextLong value) {
        if (value == null || value.isNull()) {
            nullifyDescricao();
        } else {
            aDescricao.setValue(value.getValue());
            if (aDescricao.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setDescricao(String value) {
        if (value == null) {
            nullifyDescricao();
        } else {
            aDescricao.setValue(value);
            if (aDescricao.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setDescricao(Object value) {
        aDescricao.setValue(value);
        if (aDescricao.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyDescricao() {
        if (!aDescricao.isNull()) {
            aDescricao.setNull(true);
            setModified(true);
        }
    }
    
    public DomTextLong getDescricao() {
        return aDescricao;
    }
    
    public DomTextLong oldDescricao() {
        return oDescricao;
    }
    
    public String valueOfDescricao() {
        return aDescricao.getValue();
    }
    
    public boolean isDescricaoModified() {
        return aDescricao.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo DOMINIO">
    
    public EntPreferencias dominio(String value) {
        setDominio(value);
        return this;
    }
    
    public void setDominio(DomUpper value) {
        if (value == null || value.isNull()) {
            nullifyDominio();
        } else {
            aDominio.setValue(value.getValue());
            if (aDominio.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setDominio(String value) {
        if (value == null) {
            nullifyDominio();
        } else {
            aDominio.setValue(value);
            if (aDominio.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setDominio(Object value) {
        aDominio.setValue(value);
        if (aDominio.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyDominio() {
        if (!aDominio.isNull()) {
            aDominio.setNull(true);
            setModified(true);
        }
    }
    
    public DomUpper getDominio() {
        return aDominio;
    }
    
    public DomUpper oldDominio() {
        return oDominio;
    }
    
    public String valueOfDominio() {
        return aDominio.getValue();
    }
    
    public boolean isDominioModified() {
        return aDominio.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo POR_USUARIO">
    
    public EntPreferencias porUsuario(String value) {
        setPorUsuario(value);
        return this;
    }
    
    public void setPorUsuario(DomFlag value) {
        if (value == null || value.isNull()) {
            nullifyPorUsuario();
        } else {
            aPorUsuario.setValue(value.getValue());
            if (aPorUsuario.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPorUsuario(String value) {
        if (value == null) {
            nullifyPorUsuario();
        } else {
            aPorUsuario.setValue(value);
            if (aPorUsuario.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPorUsuario(Object value) {
        aPorUsuario.setValue(value);
        if (aPorUsuario.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyPorUsuario() {
        if (!aPorUsuario.isNull()) {
            aPorUsuario.setNull(true);
            setModified(true);
        }
    }
    
    public DomFlag getPorUsuario() {
        return aPorUsuario;
    }
    
    public DomFlag oldPorUsuario() {
        return oPorUsuario;
    }
    
    public String valueOfPorUsuario() {
        return aPorUsuario.getValue();
    }
    
    public boolean isPorUsuarioModified() {
        return aPorUsuario.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo VALOR">
    
    public EntPreferencias valor(String value) {
        setValor(value);
        return this;
    }
    
    public void setValor(DomTextLong value) {
        if (value == null || value.isNull()) {
            nullifyValor();
        } else {
            aValor.setValue(value.getValue());
            if (aValor.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setValor(String value) {
        if (value == null) {
            nullifyValor();
        } else {
            aValor.setValue(value);
            if (aValor.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setValor(Object value) {
        aValor.setValue(value);
        if (aValor.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyValor() {
        if (!aValor.isNull()) {
            aValor.setNull(true);
            setModified(true);
        }
    }
    
    public DomTextLong getValor() {
        return aValor;
    }
    
    public DomTextLong oldValor() {
        return oValor;
    }
    
    public String valueOfValor() {
        return aValor.getValue();
    }
    
    public boolean isValorModified() {
        return aValor.isModified();
    }
    // </editor-fold>
    // </editor-fold>
    
    @Override
    protected void processDeleteCascade() throws AdsException {
        // Delete cascade RTPREF.PREFERENCIAS_USUARIOS.FK_PRUS_PREF
        {
            EntPreferenciasUsuarios preferenciasUsuarios = new EntPreferenciasUsuarios(ctx);
            preferenciasUsuarios.del("select id from PREFERENCIAS_USUARIOS where PREFERENCIA_ID = " + valueOfId());
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="getErrors">
    /**
     * Traduz um erro recebido do banco de dados para um AdsException
     */
    @Override
    public AdsException getErrors(String errorMsg, int transaction) {
        AdsException e;
        String msg = errorMsg.toUpperCase();
        
        if (transaction == DELETE_TRANSACTION) {
            e = new AdsException("RTPREF.PREFERENCIAS.GET_ERRORS_UNKNOWN",
                    AdsException.UNKNOWN,
                    "Erro não esperado: " + errorMsg);
        } else {
            if (msg.indexOf("UK_PREF_PREFERENCIA") >= 0) {
                e = new AdsException("RTPREF.PREFERENCIAS.UK_PREF_PREFERENCIA", 
                        Severity.ERROR,
                        "Registro duplicado! Preferência ${PREFERENCIA} (UK_PREF_PREFERENCIA)");
                return e;
            } else if (msg.indexOf("PK_PREF") >= 0) {
                e = new AdsException("RTPREF.PREFERENCIAS.PK_PREF", 
                        Severity.ERROR,
                        "ID duplicado! (PK_PREF)");
                return e;
            } else {
                e = new AdsException("RTPREF.PREFERENCIAS.GET_ERRORS_UNKNOWN",
                        AdsException.UNKNOWN,
                        "Erro não esperado: " + errorMsg);
            }
        }
        return e;
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Entity Information">
    
    public String getEntityName() {
        return ENTITY_NAME;
    }
    
    public String getTableName() {
        return TABLE_NAME;
    }
    
    public String idSequenceName() {
        return "PK_SEQUENCE";
    }
    
    private ArrayList<Field> allAttributes;
    public ArrayList<Field> getAllAttributes() {
        if (allAttributes == null) {
            allAttributes = new ArrayList<Field>();
            allAttributes.add(aId);
            allAttributes.add(aPreferencia);
            allAttributes.add(aDescricao);
            allAttributes.add(aDominio);
            allAttributes.add(aPorUsuario);
            allAttributes.add(aValor);
        }
        return allAttributes;
    }
    
    /**
     * Retorna o valor da primeira UK da entidade
     * Se ela for composta, retorna a concatenação de toda a combinação
     * de atributos separados por um espaço.
     */
    public String valueOfUk() {
        return getPreferencia().toString();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Relationships">
    
    
    public void findByPreferencia(String preferencia) throws AdsException {
        findBy(new String[] {"PREFERENCIA"},
                new Object[] {preferencia});
    }
    /**
     * Retorna os registros de PREFERENCIAS_USUARIOS que referenciam este registro através do atributo PREFERENCIA_ID
     */
    public EntPreferenciasUsuarios findAllPreferenciasUsuariosPreferencia() throws AdsException {
        return findAllPreferenciasUsuariosPreferencia("order by ID");
    }
    
    /**
     * Retorna os registros de PREFERENCIAS_USUARIOS que referenciam este registro através do atributo PREFERENCIA_ID
     */
    public EntPreferenciasUsuarios findAllPreferenciasUsuariosPreferencia(String sqlAppend) throws AdsException {
        EntPreferenciasUsuarios out = new EntPreferenciasUsuarios(ctx);
        out.find("select ID from PREFERENCIAS_USUARIOS where PREFERENCIA_ID = " + valueOfId() + " " + sqlAppend);
        return out;
    }
    
    
    /**
     * Método que copia os valores dos atributos
     * para os valores respectivos old 
     */
    public void saveOldAtributes() {
        oValor.setValue(aValor);
        oPreferencia.setValue(aPreferencia);
        oDescricao.setValue(aDescricao);
        oDominio.setValue(aDominio);
        oId.setValue(aId);
        oPorUsuario.setValue(aPorUsuario);
    }
    
    /**
     * Método que retorna as regras da entidade
     * @return ArrayList com as regras ou null caso não existir nenhuma regra
     */
    public ArrayList getAllRules() {
        ArrayList<EntityRule> out = new ArrayList<EntityRule>();
        {
            PrimaryKeyRule rule = new PrimaryKeyRule();
            rule.setEntity(EntPreferencias.class);
            rule.setName("PK_PREF");
            rule.setPkAttribute(new DomId("ID",""));
            out.add(rule);
        }
        {
            UniqueKeyRule rule = new UniqueKeyRule();
            rule.setEntity(EntPreferencias.class);
            rule.setName("UK_PREF_PREFERENCIA");
            rule.addAttribute(new DomUpper("PREFERENCIA",""));
            out.add(rule);
        }
        return out;
    }
    // </editor-fold>
    
    @Override
    protected void posInsert() throws AdsException {
        atualizarConfig(); //Atualizar Config
    }
    
    @Override
    protected void preUpdate() throws AdsException {
        // Verificar preferências de usuários
        {
            ctx.logStart("ENT-EVE", "RTPREF.PREFERENCIAS", "Verificar preferências de usuários");
            verificarUsuarios();
            ctx.logFinish();
        }
    }
    
    @Override
    protected void posUpdate() throws AdsException {
        atualizarConfig(); //Atualizar Config
    }
    
    @Override
    protected void posDelete() throws AdsException {
        atualizarConfig(); //Atualizar Config
    }
    
    @Override
    public void fillDefaultValues() throws AdsException {
        if (aId.isNull()) {
            aId.setValue("" + ctx.getNextVal("pk_sequence"));
        }
        if (getDescricao().isNull()) {
            setDescricao(getDescricao().getDefaultValue());
        }
        if (getDominio().isNull()) {
            setDominio(getDominio().getDefaultValue());
        }
        if (getPorUsuario().isNull()) {
            setPorUsuario(getPorUsuario().getDefaultValue());
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="Métodos customizados">
    
    /**
     * Notify.
     * <p>
     * Notificação de eventos.
     */
    public void notify(String eventoName, Object log) throws AdsException {
        // <user-code id="19417437" parentId="19417420" hashcode="-6493a51f" length="259">
        // import br.com.telescope.replicator.DmlLog;
        if (log instanceof DmlLog) {
            DmlLog dlog = (DmlLog) log;
            Long id = dlog.getOriginRecordId();
            EntPreferencias pref = new EntPreferencias(ctx);
            pref.findById(id);
            pref.atualizarConfig();
        }
        // </user-code>
    }
    
    /**
     * Verificar preferências de usuários.
     * <p>
     * Se a preferência for informada com POR_USUARIO="N", então não devem 
     * existir preferências de usuários.
     */
    private void verificarUsuarios() throws AdsException {
        // <user-code id="793693" parentId="8825" hashcode="-1c212106" length="85">
        if (valueOfPorUsuario().equals("N")) {
        // TODO: Excluir preferencias de usuario
        }
        
        // </user-code>
    }
    
    /**
     * Regra de ação: Atualizar Config
     */
    private void atualizarConfig() throws AdsException {
        // <user-code id="793702" parentId="793697" hashcode="6349df65" length="676">
        // import br.com.telescope.t2.config.Config;
        // import java.util.Map;
        // import br.com.telescope.t2.config.ConfigParameter;
        Config cfg = Config.getInstance();
        if (currentTransaction == DELETE_TRANSACTION) {
            cfg.setParameter(valueOfPreferencia(), null);
        } else {
            Map<String, ConfigParameter> map = cfg.getParametersMap();
            ConfigParameter cp = cfg.getParametersMap().get(valueOfPreferencia());
            if (cp == null) {
                cp = new ConfigParameter();
                cp.setKey(valueOfPreferencia());
                cp.setValue(valueOfValor());
                cp.initOldValue();
                map.put(cp.getKey(), cp);
            } else {
                cp.setValue(valueOfValor());
            }
        }
        // </user-code>
    }
    
    // <editor-fold defaultstate="collapsed" desc="Cache">
    private static Hashtable<Long,EntPreferencias> entityCache;
    
    
    private static void initCache() {
        if (entityCache == null) entityCache = new Hashtable();
        
    }
    
    private static void clearCache() {
        entityCache = null;
        
    }
    
    private static void putCache(EntPreferencias ent) {
        if (ent != null) {
            EntPreferencias rec = new EntPreferencias();
            rec.setAllAttributes(ent);
            entityCache.put(rec.valueOfId(), rec);
            
        }
    }
    
    private static void removeCache(EntPreferencias rec) {
        entityCache.remove(rec.oldId().getValue());
        
    }
    
    private static EntPreferencias getCacheById(long id) {
        return entityCache.get(id);
    }
    // </editor-fold>
}
